﻿using DNFImagePacks2Manager.Helpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace DNFImagePacks2Manager.NPK
{
    public class NeopleBKHeader
    {
        private byte[] neopleMagic;
        private byte[] neopleOne;
        private byte[] neopleTwo;
        private byte[] bkSize;
        private byte[] allSize;

        public string NeopleMagic => ByteHelper.Bytes2AsciiString(neopleMagic);
        public int NeopleOne => ByteHelper.Bytes2Int(neopleOne);
        public int NeopleTwo => ByteHelper.Bytes2Int(neopleTwo);
        public int BKSize => ByteHelper.Bytes2Int(bkSize);
        public int AllSize => ByteHelper.Bytes2Int(allSize);

        public NeopleBKHeader(BinaryReader reader)
        {
            neopleMagic = reader.ReadBytes(16);
            neopleOne = reader.ReadBytes(4);
            neopleTwo = reader.ReadBytes(4);
            bkSize = reader.ReadBytes(4);
            allSize = reader.ReadBytes(4);
        }
    }


    public class BKFile
    {
        NeopleBKHeader neopleHeader;
        byte[] bkData;
        byte[] neopleExtra;

        byte[] signature;
        byte[] codec;
        byte[] size;
        byte[] frameCount;
        byte[] largestSize;
        byte[] frameCountAgain;
        byte[] videoWidth;
        byte[] videoHeight;
        byte[] fpsDividend;
        byte[] fpsDivider;
        byte[] videoFlag;
        byte[] audioCount;


        public BKFile(string path)
        {
            using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
            using var reader = new BinaryReader(fileStream);
            neopleHeader = new NeopleBKHeader(reader);
            Debug.WriteLine($"{neopleHeader.NeopleMagic} {neopleHeader.NeopleOne} {neopleHeader.NeopleTwo} {neopleHeader.BKSize} {neopleHeader.AllSize}");
            reader.BaseStream.Position = neopleHeader.BKSize+32;
            neopleExtra = reader.ReadBytes(neopleHeader.AllSize-(int)reader.BaseStream.Position);
            Debug.WriteLine(ByteHelper.Bytes2ByteString(neopleExtra));
            reader.BaseStream.Position = 32;
            signature = reader.ReadBytes(3);
            codec = reader.ReadBytes(1);
            size = reader.ReadBytes(4);
            frameCount = reader.ReadBytes(4);
            largestSize = reader.ReadBytes(4);
            frameCountAgain = reader.ReadBytes(4);
            videoWidth = reader.ReadBytes(4);
            videoHeight = reader.ReadBytes(4);
            fpsDividend = reader.ReadBytes(4);
            fpsDivider = reader.ReadBytes(4);
            videoFlag = reader.ReadBytes(4);
            audioCount = reader.ReadBytes(4);
            Debug.WriteLine($"{ByteHelper.Bytes2AsciiString(signature)} {ByteHelper.Bytes2AsciiString(codec)} {ByteHelper.Bytes2Int(size)}");
            Debug.WriteLine($"{ByteHelper.Bytes2Int(frameCount)} {ByteHelper.Bytes2Int(largestSize)} {ByteHelper.Bytes2Int(frameCountAgain)}");
            Debug.WriteLine($"{ByteHelper.Bytes2Int(videoWidth)} {ByteHelper.Bytes2Int(videoHeight)} {ByteHelper.Bytes2Int(fpsDividend)} {ByteHelper.Bytes2Int(fpsDivider)} {ByteHelper.Bytes2ByteString(videoFlag)} {ByteHelper.Bytes2Int(audioCount)}");
            reader.BaseStream.Position = 40;
            //bkData = reader.ReadBytes(neopleHeader.BKSize);
            int length = neopleHeader.AllSize - 40;
            List<byte> list = [];
            list.AddRange(signature);
            list.AddRange(codec);
            list.AddRange(ByteHelper.Int2Bytes(length));
            byte[] data = reader.ReadBytes(length);
            bkData = [.. list.Concat(data)];
        }

        public async Task<string> WriteToTempFile()
        {
            string bk2Path = Path.Combine(Path.GetTempPath(), $"bk2_extract_{Guid.NewGuid():N}.bk2");
            using (var stream = File.OpenWrite(bk2Path))
            {
                await stream.WriteAsync(bkData);
                await stream.FlushAsync();
            }
            return bk2Path;
        }
    }
}